package com.pp.proposalPrint.client;

import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.NumberCell;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.IdentityColumn;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ProvidesKey;
import com.pp.proposalPrint.shared.ProposalContent;
import com.pp.proposalPrint.shared.ProposalContentList;

public abstract class ProposalTable<T extends ProposalContentList<C>, C extends ProposalContent> {
		
	/**
	 * The key provider that allows to identify Materials even if a field
	 * changes. Materials are identified by their unique ID.
	 */
	private final ProvidesKey<C> KEY_PROVIDER = new ProvidesKey<C>() {
		@Override
		public Object getKey(C item) {
			return item.getId();
		}
	};
	
	protected CellTable<C> ctProposalContentTable = new CellTable<C>(KEY_PROVIDER);
	
	// Vertical panel for proposal content list
	protected VerticalPanel vPnlProposalContentList = new VerticalPanel();
		
	// Logger
	protected static Logger logger = Logger.getLogger("ProposalPrint");

	// List of proposal content
	private T proposalContentsList;
	
	// The header of the table
	protected String proposalContentListHeader;
	
	// Column widths
	//private static final int PROPOSAL_CONTENT_NO     =  25;
	private static final int PROPOSAL_CONTENT_NAME   = 400;
	//private static final int PROPOSAL_CONTENT_TOTAL  =  75;
	//private static final int PROPOSAL_CONTENT_DELETE =  25;
	
	// Constructor
	public ProposalTable(T contentsList, String header) {
		this.proposalContentsList      = contentsList;
		this.proposalContentListHeader = header;
	}
	

	/**
	 * This method loads the table with header.
	 */
	protected void loadTable() {
				
		VerticalPanel vPnlMain = (VerticalPanel) RootPanel.get("proposalprint").getWidget(0);
		
		vPnlProposalContentList.setBorderWidth(1);
		vPnlMain.add(vPnlProposalContentList);
		vPnlProposalContentList.setWidth("100%");
		
		// Horizontal panel inside proposal content list panel for proposal content header
		HorizontalPanel hPnlProposalContentListHeader = new HorizontalPanel();
		vPnlProposalContentList.add(hPnlProposalContentListHeader);
		
		// Label for proposal content list panel
		Label lblIProposalContentListHeader = new Label(this.proposalContentListHeader);
		hPnlProposalContentListHeader.add(lblIProposalContentListHeader);
		
		// Button for adding new row into the table
		Button btnAddNewRow = new Button("Add");
		btnAddNewRow.setTabIndex(2);
		btnAddNewRow.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				C newRow = (C) proposalContentsList.getNewContent();
				if(newRow != null) {
					proposalContentsList.add(newRow);
				}
				proposalContentsList.reorder();
				ctProposalContentTable.setRowData(proposalContentsList.getContentList());
				ctProposalContentTable.redraw();
				updateProposalContentListCalculations();
			}
		});
		btnAddNewRow.setText("Add");
		hPnlProposalContentListHeader.add(btnAddNewRow);
		
		vPnlProposalContentList.add(ctProposalContentTable);
		
		// Create the number column
		final NumberCell nClNumber = new NumberCell();
		Column<C, Number> cNumber = new Column<C, Number>(nClNumber) {
			@Override
			public Integer getValue(C object) {
				// Return the number as the value of this column.
				return object.getNo();
			}
		};
		ctProposalContentTable.addColumn(cNumber, "No");
		
		// Create the name column
		final TextInputCellStyled tIClName = new TextInputCellStyled(PROPOSAL_CONTENT_NAME);
		Column<C, String> cProposalContent = new Column<C, String>(tIClName) {
			@Override
			public String getValue(C object) {
				// Return the material as the value of this column.
				return object.getName();
			}
		};
		ctProposalContentTable.addColumn(cProposalContent, "Material");
		// Add a field updater to save the new value.
		cProposalContent.setFieldUpdater(new FieldUpdater<C, String>() {
			@Override
			public void update(int index, C object, String value) {
				// Push the changes into the Material.
				object.setName(value);
				// Redraw the table with the new data.
				ctProposalContentTable.redraw();
				// Log the array for debugging purposes
				logger.log(Level.ALL, "[ProposalPrint]: material updated: id: " + object.getId());
				for(C c : proposalContentsList.getContentList()) {
					logger.log(Level.ALL, "[ProposalPrint]: id: " + c.getId() + ", name: " + c.getName());
				}
			}
		});

	}
	
	
	protected void loadLastColumn() {
		
		// Create the delete button
		final ActionCell<C> aCDelete = new ActionCell<C>("Delete", new ActionCell.Delegate<C>() {
			@Override
			public void execute(C object) {
				// Do the deletion here
				if(object != null) {
					proposalContentsList.remove(object);
				}
				proposalContentsList.reorder();
				ctProposalContentTable.setRowData(proposalContentsList.getContentList());
				ctProposalContentTable.redraw();
				updateProposalContentListCalculations();
			}
		});
		IdentityColumn<C> cDelete = new IdentityColumn<C>(aCDelete) {
			@Override
			public C getValue(C c) {
				return c;
			}
		};
		ctProposalContentTable.addColumn(cDelete);
		
		// Push the data into the widget.
		ctProposalContentTable.setRowData(proposalContentsList.getContentList());	
	}
	
	// Loads the footer element of the table
	protected abstract void loadFooter();
	
	// Builds up the table
	public abstract void build();

	protected abstract void updateProposalContentListCalculations();
	
}
